/****h* scdbxml/parse.c
 *  NAME
 *    parse.c
 *  DESCRIPTION
 *    Command line tool for parsing and inserting XML documents into an SQL database.
 *********/
#include "parse.h"

/****f* parse.c/main
 *  NAME
 *    main
 *  SYNOPSIS
 *    int main(int argc, char **argv) 
 *  ARGUMENTS
 *    argc - int - the number of arguments
 *    argv - char ** - list of arguments
 *  RETURN TYPE
 *    int - EXIT_SUCCESS for success, EXIT_FAILURE for error
 *  AUTHOR
 *    Swithun Crowe
 *  SOURCE
*/
int main(int argc, char **argv) 
	/*{{{*/
{
	 xmlSAXHandler sax = {
			NULL, /* internalSubset */
				NULL, /* isStandalone */
				NULL, /* hasInternalSubset */
				NULL, /* hasExternalSubset */
				NULL, /* resolveEntity */
				callBackGetEntity, /* getEntity */
				callBackEntity, /* entityDecl */
				NULL, /* notationDecl */
				NULL, /* attributeDecl */
				NULL, /* elementDecl */
				NULL, /* unparsedEntityDecl */
				NULL, /* setDocumentLocator */
				callBackDocumentStart, /* startDocument */
				callBackDocumentEnd, /* endDocument */
				NULL, /* startElement */
				NULL, /* endElement */
				NULL, /* reference */
				callBackChars, /* characters */
				NULL, /* ignorableWhitespace */
				callBackPI, /* processingInstruction */
				callBackCom, /* comment */
				NULL, /* xmlParserWarning */
				callBackError, /* xmlParserError */
				NULL, /* xmlParserError */
				NULL, /* getParameterEntity */
				NULL, /* cdataBlock; */
				NULL, /* externalSubset; */
				XML_SAX2_MAGIC,
				NULL,
				callBackElementNSStart, /* startElementNs */
				callBackElementNSEnd, /* endElementNs */
				NULL  /* xmlStructuredErrorFunc */
	 };
	 
	 userWriterCtxt ctxt = NULL;
	 int i, ret, buffer_max, buffer_len, read;
	 char *buffer, *line;
	 FILE *fh;
	 
	 ret = EXIT_FAILURE;
	 
	 while (1) 
		 {
				if (argc < 3) 
					{
						 printf("Usage: %s database xmlfile [xmlfile ...]\n", argv[0]);
						 break;
					}
				
				/*
				 * initialise context and parser
				 * and allocate space for reading lines into buffer
				 */
				ctxt = userWriterCtxtInitialise(argv[1]);
				xmlDefaultSAXHandlerInit();
				
				line = (char *) malloc(sizeof(char) * MAX_READ);
				if (NULL == line) 
					{
						 userWriterCtxtError(ctxt, SCDBXML_MALLOC, __LINE__, __FILE__);
						 break;
					}
				
				buffer = (char *) malloc(sizeof(char) * MAX_READ);
				if (NULL == buffer) 
					{
						 userWriterCtxtError(ctxt, SCDBXML_MALLOC, __LINE__, __FILE__);
						 break;
					}
				buffer_max = MAX_READ;
				
				/*
				 * loop over file names from command line,
				 * remembering file name and
				 * reading file into buffer, line by line
				 */
				for (i = 2; i < argc; ++ i) 
					{
						 userWriterCtxtSetFile(ctxt, argv[i]);
						 
						 fh = fopen(argv[i], "r");
						 if (!fh) 
							 {
									userWriterCtxtError(ctxt, SCDBXML_FILE, __LINE__, __FILE__);
									break;
							 }
						 
						 /*
							* read until EOF
							*/
						 buffer_len = 0;
						 while (NULL != fgets(line, MAX_READ, fh)) 
							 {
									/*
									 * see if buffer needs more space allocated
									 */
									read = strlen(line);
									if (buffer_len + read > buffer_max) 
										{
											 buffer_max *= 2;
											 buffer = (char *) realloc(buffer, sizeof(char) * buffer_max);
											 
											 if (NULL == buffer) 
												 {
														userWriterCtxtError(ctxt, SCDBXML_MALLOC, __LINE__, __FILE__);
														break;
												 }
										}
									
									/*
									 * append line to buffer
									 */
									memcpy((void *) &buffer[buffer_len], line, read);
									buffer_len += read;
							 }
						 
						 /*
							* finished reading file,
							* so check for error,
							* close file and parse buffer
							*/
						 if (SCDBXML_OK != ctxt->error) 
							 {
									break;
							 }
						 
						 fclose(fh);
						 
						 /*xmlSAXUserParseFile(&sax, (void *) ctxt, argv[i]);*/
						 xmlSAXUserParseMemory(&sax, (void *) ctxt, buffer, buffer_len);
						 if (SCDBXML_OK != ctxt->error) 
							 {
									break;
							 }
					} /* end of loop over files */
				
				if (SCDBXML_OK != ctxt->error) 
					{
						 break;
					}
				
				/*
				 * finished with line and buffer and context
				 */
				userWriterCtxtFinish(ctxt);
				if (SCDBXML_OK != ctxt->error) 
					{
						 break;
					}
				
				free(ctxt);
				free(line);
				free(buffer);
				
				ret = EXIT_SUCCESS;
				break;
		 }

	 if (EXIT_SUCCESS != ret && 
			 NULL != ctxt) 
		 {
				fprintf(stderr, "error: %d (%s:%d)\n", ctxt->error, ctxt->file, ctxt->line);
		 }
	 
	 return ret;
}
/*}}}*/

/************ main */
